<script setup lang="tsx">
import type { VxeGridProps } from '#/adapter/vxe-table';
import { topicAdd, topicUpdate, topicRemove } from '#/api/clinical/topic';
import { computed, nextTick, onMounted, watch } from 'vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { Input, message, Space, Popconfirm } from 'ant-design-vue';
import { getVxePopupContainer } from '@vben/utils';
import { cloneDeep } from '@vben/utils';
import { useAccess } from '@vben/access';
import type { TopicVO } from '#/api/clinical/topic/model';


defineOptions({
  name: 'TopicTable',
});

const props = withDefaults(
  defineProps<{
    topics: TopicVO[];
    projectId: string | number | undefined;
  }>(),
  {
    topics: () => [],
  },
);

const emit = defineEmits(['change']);

const gridOptions: VxeGridProps = {
  editConfig: {
    trigger: 'manual',
    mode: 'row',
    showStatus: true,
  },
  border: true,
  rowConfig: {
    drag: true,
  },
  checkboxConfig: {},
  editRules: {
    name: [{ required: true, message: '请输入课题', trigger: 'blur' }],
  },
  columns: [
    {
      field: 'name',
      title: '课题名称',
      align: 'center',
      editRender: {},
      slots: {
        default: ({ row }) => {
          if (!row.name) {
            return <span class="text-red-500">未填写</span>;
          }
          return <span>{row.name}</span>;
        },
        edit: ({ row }) => {
          return <Input placeholder={'请输入'} v-model:value={row.name} />;
        },
      },
    },
    {
      field: 'action',
      title: '操作',
      width: 200,
      slots: { default: 'action' },
      className: 'no-edit-indicator',
    },
  ],
  height: 'auto',
  keepSource: true,
  pagerConfig: {
    enabled: false,
  },
  proxyConfig: {
    enabled: false,
  },
  showOverflow: false,
  toolbarConfig: {
    refresh: false, // 默认刷新按钮
    zoom: true, // 默认全屏按钮
    custom: false,
  },
};

const [BasicTable, tableApi] = useVbenVxeGrid({
  gridOptions,
});

onMounted(() => {
  watch(
    () => props.topics,
    async (topics) => {
      await nextTick();
      const clonedTopics = cloneDeep(topics);
      await tableApi.grid.loadData(clonedTopics);
    },
    { immediate: true, deep: true },
  );
});

async function handleAdd() {
  // 1. 获取所有已插入但未保存的记录
  const insertRecords = tableApi.grid.getInsertRecords();
  // 2. 遍历这些未保存的记录
  for (const record of insertRecords) {
    try {
      // 3. 对每一条进行校验
      const err = await tableApi.grid.validate(record);
      if (err) {
        // 4. 如果任何一条校验失败，就弹出提示并终止操作
        message.error('请先完成并保存当前正在新增的课题');
        return;
      }
      // 5. 如果校验成功，就调用保存逻辑
      await handleSave(record);
    } catch (error) {
      // 6. 如果保存过程中出现API错误等，也要提示并终止
      console.error('保存上一条课题时出错:', error);
      message.error('保存上一条课题时出错，请检查网络或联系管理员');
      return;
    }
  }

  // 7. 只有当所有之前的“新行”都成功保存后，才插入一个全新的空行
  const { row: newRow } = await tableApi.grid.insert({ name: '' });
  await tableApi.grid.setEditRow(newRow);
}

async function handleDelete(row: TopicVO) {
  // (这部分自动保存的逻辑保持不变)
  const dirtyRecords = [
    ...tableApi.grid.getInsertRecords(),
    ...tableApi.grid.getUpdateRecords(),
  ];
  if (dirtyRecords.length > 0) {
    for (const record of dirtyRecords) {
      const isSuccess = await handleSave(record);
      if (!isSuccess) {
        message.error('请先完成并保存所有正在编辑的课题');
        return;
      }
    }
  }
  try {
    // 只有在数据库中有记录时才调用API
    if (row.id) {
      await topicRemove(row.id);
    }
    // API成功后，才从UI上移除，并提示成功
    await tableApi.grid.remove(row);
    const { tableData } = tableApi.grid.getTableData();
    emit('change', cloneDeep(tableData));
  } catch (error) {
    // 如果API失败，则进入catch块
    console.error('删除课题失败:', error);
    message.error('删除失败，请检查网络或联系管理员');
  }
}

async function handleEdit(row: TopicVO) {
  await tableApi.grid.setEditRow(row);
}

async function handleSave(row: TopicVO): Promise<boolean> {
  const err = await tableApi.grid.validate(row);
  if (err) {
    return false;
  }

  try {
    Object.assign(row, { projectId: props.projectId });
    // 将API调用包裹在try块中
    if (row.id) {
      await topicUpdate(row);
    } else {
      const newTopicId = await topicAdd(row);
      Object.assign(row, { id: newTopicId });
    }
    // 只有在API成功后，才清除编辑状态并返回成功
    await tableApi.grid.clearEdit();
    const { tableData } = tableApi.grid.getTableData();
    emit('change', cloneDeep(tableData));
    return true;
  } catch (error) {
    // 如果API调用失败，则进入catch块
    console.error('保存课题失败:', error);
    message.error('保存失败，请检查网络或联系管理员');

    // 关键：返回false，并且不清除编辑状态，让用户可以重试
    return false;
  }
}
const { hasAccessByRoles } = useAccess();
const isAdmin = computed(() => {
  return hasAccessByRoles(['admin', 'superadmin']);
});
</script>

<template>
  <BasicTable>
    <template #toolbar-tools>
      <Space>
        <a-button type="primary" @click="handleAdd">新增课题</a-button>
      </Space>
    </template>

    <template #action="{ row, $table }">
      <Space
        ><template v-if="$table.isEditByRow(row)">
          <ghost-button
            @click="handleSave(row)"
            v-access:code="['business:topic:add']"
            >保存</ghost-button
          >
        </template>
        <template v-else>
          <ghost-button
            @click="handleEdit(row)"
            v-access:code="['business:topic:edit']"
            >编辑</ghost-button
          >
        </template>
        <Popconfirm
          :get-popup-container="getVxePopupContainer"
          placement="left"
          title="确认删除？"
          @confirm="handleDelete(row)"
        >
          <ghost-button
            danger
            v-access:code="['business:topic:remove']"
            v-if="isAdmin"
            @click.stop=""
          >
            {{ $t('pages.common.delete') }}
          </ghost-button>
        </Popconfirm>
      </Space>
    </template>
  </BasicTable>
</template>

<style lang="scss" scoped>
:deep .no-edit-indicator::before {
  display: none !important;
}
</style>
